package com.txzt.gaea.business.plan.controller;

import com.alibaba.fastjson.JSON;
import com.txzt.base.constant.RtnConstant;
import com.txzt.base.core.RtnInfo;
import com.txzt.gaea.aspect.annotation.SysDataPermission;
import com.txzt.gaea.base.service.DataPermissionService;
import com.txzt.gaea.base.service.DictInfoService;
import com.txzt.gaea.business.plan.domain.model.PlanInfo;
import com.txzt.gaea.business.plan.domain.query.PlanInfoQuery;
import com.txzt.gaea.business.plan.domain.req.BatchExamineReqItem;
import com.txzt.gaea.business.plan.service.IPlanInfoService;
import com.txzt.gaea.business.util.TranslateUtil;
import com.txzt.gaea.common.annotation.EntityCommonValue;
import com.txzt.gaea.common.base.controller.BaseController;
import com.txzt.gaea.common.core.base.context.AdminUserContext;
import com.txzt.gaea.common.enums.FlowFlagEnum;
import com.txzt.gaea.common.enums.IsDeleteEnum;
import com.txzt.gaea.common.enums.PlanStatus;
import com.txzt.gaea.flow.model.FlowBizModel;
import com.txzt.gaea.flow.service.FlowService;
import com.txzt.gaea.flow.vo.FlowBizStepVo;
import com.txzt.gaea.provide.service.biz.FileInfoBizService;
import com.txzt.gaea.vo.AdminUserVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.beetl.sql.core.engine.PageQuery;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecgframework.poi.word.WordExportUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/plan/info")
public class PlanInfoController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(PlanInfoController.class);

    @Autowired
    private IPlanInfoService planInfoService;
    @Autowired
    private FlowService flowService;
    @Autowired
    private DataPermissionService dataPermissionService;
    @Autowired
    private DictInfoService dictInfoService;

    @Value("${template.path}")
    String templatePath;


    /**
     * 分页查询
     * @param pageNumber
     * @param pageSize
     * @param planInfoQuery
     * @return
     */
    @SysDataPermission
    @GetMapping(value = "/list")
    public RtnInfo<?> pageList(@RequestParam(defaultValue = "1") Integer pageNumber,
                            @RequestParam(defaultValue = "10") Integer pageSize, PlanInfoQuery planInfoQuery) {
        PageQuery<PlanInfo> pageList = planInfoService.pageQuery(new PageQuery<>(pageNumber, pageSize, planInfoQuery));
        return RtnInfo.success(this.translate(pageList));
    }

    /**
     * 分页查询(计划审核)
     * @param pageNumber
     * @param pageSize
     * @param planInfoQuery
     * @return
     */
    @SysDataPermission
    @GetMapping(value = "/listCheck")
    public RtnInfo<?> listCheck(@RequestParam(defaultValue = "1") Integer pageNumber,
                               @RequestParam(defaultValue = "10") Integer pageSize, PlanInfoQuery planInfoQuery) {
//        if(planInfoQuery.getCurrentStepMember()==null){
//            //当前用户角色
//            String[] split = AdminUserContext.getUser().getRoleid().split(",");
//            List<Long> roleIds = new ArrayList<>();
//            for (String s : split) {
//                if (StringUtils.isNotBlank(s)){
//                    roleIds.add(Long.valueOf(s));
//                }
//            }
//            if (roleIds.size()>0){
//                planInfoQuery.setRoleIds(roleIds);
//            }
//        }
        PageQuery<PlanInfo> pageList = planInfoService.pageQuery("planInfo.selectPlanCheckList", new PageQuery<>(pageNumber, pageSize, planInfoQuery));
        return RtnInfo.success(this.translate(pageList));
    }

    /**
     * 查询待审核数量(计划审核)
     * @param planInfoQuery
     * @return
     */
    @SysDataPermission
    @GetMapping(value = "/listCheckCount")
    public RtnInfo<?> listCheckCount(PlanInfoQuery planInfoQuery) {
        Long count = planInfoService.listCheckCount(planInfoQuery);
        return RtnInfo.success(count);
    }

    private PageQuery<PlanInfo> translate(PageQuery<PlanInfo> pageList){
        pageList.getList().forEach(item -> {
            //翻译创建人
            item.setCreateName(TranslateUtil.getUserName(item.getCreateBy()));
            //翻译更新人
            item.setUpdateName(TranslateUtil.getUserName(item.getUpdateBy()));
            //翻译编报人
            if (null != item.getWriteBy()) {
                item.setWriteName(TranslateUtil.getUserName(item.getWriteBy()));
            }
            //翻译下发人
            if (null != item.getAssignBy()){
                item.setAssignName(TranslateUtil.getUserName(item.getAssignBy()));
            }
            //翻译项目组长
            if (null != item.getProjectLeader()){
                item.setProjectLeaderName(TranslateUtil.getUserName(item.getProjectLeader()));
            }
            //翻译承担部门（离大谱）
            item.setDepartName(TranslateUtil.getDepartmentName(item.getDepartId()));

            item.setDeptName(TranslateUtil.getDepartmentName(item.getDeptId()));
        });
        return pageList;
    }


    /**
     * 分页查询未在计划下发中的项目
     * @param pageNumber
     * @param pageSize
     * @param planInfoQuery
     * @return
     */
    @SysDataPermission
    @GetMapping(value = "/listWithoutPackId")
    public RtnInfo<?> listWithoutPackId(@RequestParam(defaultValue = "1") Integer pageNumber,
                               @RequestParam(defaultValue = "10") Integer pageSize, PlanInfoQuery planInfoQuery) {
        planInfoQuery.setWithoutPackIdFlag(true);
        return RtnInfo.success(planInfoService.pageQuery(new PageQuery<>(pageNumber, pageSize, planInfoQuery)));
    }

    /**
     * 计划统计
     * @return
     */
    @GetMapping(value = "/statistics")
    public RtnInfo<?> statistics() {
        return RtnInfo.success(planInfoService.statisticsPlanInfo());
    }


    /**
     * 查询计划最新审批记录
     * @return
     */
    @GetMapping(value = "/getFlow")
    public RtnInfo<?> getFlow(@RequestParam Long id) {
        return RtnInfo.success(flowService.getFlowBizStep(id,FlowFlagEnum.MAKING_PLAN.getCode()));
    }

    /**
     * 查询流程步骤
     * @return
     */
    @GetMapping(value = "/selectFlowStep")
    public RtnInfo<?> selectFlowStep(@RequestParam String flowType) {
        return RtnInfo.success(flowService.showStepList(flowType,FlowFlagEnum.MAKING_PLAN.getCode()));
    }

    /**
     * id查询计划全量信息
     * @return
     */
    @GetMapping(value = "/queryById")
    public RtnInfo<?> queryById(@RequestParam Long id) {
        return RtnInfo.success(planInfoService.selectPlanInfoById(id));
    }

    /**
     * 新增
     * @param planInfo
     * @return
     */
    @PostMapping(value = "/add")
    @EntityCommonValue(operation = "CREATE")
    public RtnInfo<?> add(@RequestBody PlanInfo planInfo) {
        int count = planInfoService.savePlanInfo(planInfo);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 更新
     * @param planInfo
     * @return
     */
    @PutMapping(value = "/editOnly")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> editOnly(@RequestBody PlanInfo planInfo) {
        int count = planInfoService.updateInfoOnly(planInfo);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 更新
     * @param planInfo
     * @return
     */
    @PutMapping(value = "/edit")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> edit(@RequestBody PlanInfo planInfo) {
        int count = planInfoService.updateInfo(planInfo);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 撤回
     * @param planInfo
     * @return
     */
    @PutMapping(value = "/revocation")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> revocation(@RequestBody PlanInfo planInfo) {
        int count = planInfoService.revocationPlanInfo(planInfo);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 批量提交计划
     * @param ids
     * @return
     */
    @GetMapping(value = "/batchSubmit")
    public RtnInfo<?> batchSubmit(@RequestParam String ids) {
        List<Long> idList = Arrays.stream(ids.split(",")).map(Long::valueOf).collect(Collectors.toList());
        idList.forEach(id ->{
            planInfoService.submitPlanInfo(id);
        });
        return RtnInfo.SUCCESS;
    }

    /**
     * 逻辑删除
     * @param id
     * @return
     */
    @DeleteMapping(value = "/delete")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> delete(@RequestParam Long id) {
        PlanInfo planInfo = new PlanInfo();
        planInfo.setId(id);
        planInfo.setIsDelete(IsDeleteEnum.DELETE.getCode());
        int count = planInfoService.updateById(planInfo);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }


    /**
     * 根据id移除已在计划下发中项目
     * @param id
     * @return
     */
    @PostMapping(value = "/removePackId")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> removePackId(@RequestParam Long id) {
        int count = planInfoService.removePackIdByIdSingle(id);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 计划编报
     * @param ids
     * @return
     */
    @GetMapping(value = "/issue")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> ISSUE(@RequestParam String ids) {
        List<Long> idList = Arrays.stream(ids.split(",")).mapToLong(Long::valueOf).boxed().collect(Collectors.toList());
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        AtomicInteger count = new AtomicInteger();
        idList.forEach(id ->{
            PlanInfo planInfo = new PlanInfo();
            planInfo.setId(id);
            planInfo.setPlanStatus(PlanStatus.PASS.getCode());
            //记录编报人及编报时间
            planInfo.setWriteBy(adminUserVO.getId());
            planInfo.setWriteTime(new Date());
            count.addAndGet(planInfoService.updateById(planInfo));
        });
        if (count.get() > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }


    /**
     * 计划下达
     * @param idList
     * @return
     */
    @PutMapping(value = "/wait")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> wait(List<Long> idList) {
        AtomicInteger count = new AtomicInteger();
        idList.forEach(id ->{
            PlanInfo planInfo = new PlanInfo();
            planInfo.setId(id);
            planInfo.setPlanStatus(PlanStatus.PASS.getCode());
            count.addAndGet(planInfoService.updateById(planInfo));
        });
        if (count.get() > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }


    /**
     * 计划下发
     * @param ids
     * @return
     */
    @GetMapping(value = "/assign")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> assign(@RequestParam String ids) {
        int count = planInfoService.assignPlanInfo(ids);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 导出excel（生成计划草案）
     */
    @Transactional(rollbackFor = Exception.class)
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(String ids) {
        return this.exportPlanInfoExcel(ids);
    }


    /**
     * 导出word（下载单条数据文档）
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @GetMapping(value = "/exportDocx")
    public void exportDocx(@RequestParam Long id, HttpServletResponse response) throws Exception {
        this.exportPlanInfoWord(id, response);
    }


    private ModelAndView exportPlanInfoExcel(String ids) {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        // 获取选择的数据
        List<Long> idList = Arrays.stream(ids.split(",")).mapToLong(Long::valueOf).boxed().collect(Collectors.toList());
        List<PlanInfo> list = planInfoService.getSelectedData(idList);
        list.forEach(l ->{
            //翻译项目组长
            l.setProjectLeaderName(TranslateUtil.getUserName(l.getProjectLeader()));
            //翻译承担部门
            l.setDepartName(TranslateUtil.getDepartmentName(l.getDepartId()));
            //翻译提报部门
            l.setDeptName(TranslateUtil.getDepartmentName(l.getDeptId()));
            //翻译状态
            l.setPlanStatusName(PlanStatus.getInfoByCode(l.getPlanStatus()));
            //翻译分类
            l.setPlanType(dictInfoService.dictTranslate("plan_type",l.getPlanType()));
            //记录生成草案时间
            PlanInfo target = new PlanInfo();
            target.setId(l.getId());
            target.setDraftTime(new Date());
            planInfoService.updateById(target);
        });
        // AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        mv.addObject(NormalExcelConstants.FILE_NAME, "计划项目");
        mv.addObject(NormalExcelConstants.CLASS, PlanInfo.class);
        ExportParams exportParams = new ExportParams("计划项目", "导出人:" + adminUserVO.getName(), "计划项目");
        mv.addObject(NormalExcelConstants.PARAMS, exportParams);
        mv.addObject(NormalExcelConstants.DATA_LIST, list);
        return mv;
    }

    /**
     * 导出word
     *
     * @return
     */
    private void exportPlanInfoWord(Long id, HttpServletResponse response) throws Exception {
        PlanInfo planInfo = planInfoService.selectById(id);
        PlanInfo target = new PlanInfo();
        target.setId(planInfo.getId());
        target.setDownloadTime(new Date());
        planInfoService.updateById(target);
        Map<String, Object> map = new HashMap<String, Object>(12);
        //计划编号
        map.put("projectNo", planInfo.getProjectNo());
        //计划分类
        map.put("planType", dictInfoService.dictTranslate("plan_type",planInfo.getPlanType()));
        //立项背景
        map.put("projectBackground", planInfo.getProjectBackground());
        //主要研究内容及要求
        map.put("researchContent", planInfo.getResearchContent());
        //成果形式
        map.put("resultForm", planInfo.getResultForm());
        //经费预算
        map.put("budgetFund", planInfo.getBudgetFund());
        //项目组长
        map.put("projectLeader", TranslateUtil.getUserName(planInfo.getProjectLeader()));
        //审核意见
        List<FlowBizStepVo> list = flowService.getFlowBizStep(planInfo.getId(), FlowFlagEnum.MAKING_PLAN.getCode());
        if (list.size() == 3) {
            if (StringUtils.isNotEmpty(list.get(2).getStepComment())) {
                map.put("room",list.get(2).getStepComment());
            }else {
                map.put("room","");
            }
            if (StringUtils.isNotEmpty(list.get(1).getStepComment())) {
                map.put("office",list.get(1).getStepComment());
            }else {
                map.put("office","");
            }
            if (StringUtils.isNotEmpty(list.get(0).getStepComment())) {
                map.put("center",list.get(0).getStepComment());
            }else {
                map.put("center","");
            }
        }
        XWPFDocument doc;
        //生成合同word文件
        System.out.println("--------------" + templatePath + "-----templatePath---------");
        doc = WordExportUtil.exportWord07(templatePath, map);
        //设置表格边框样式
        Iterator<XWPFTable> itTable = doc.getTablesIterator();
        while (itTable.hasNext()) {
            XWPFTable table = itTable.next();
            table.setBottomBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 4, "000000");
            table.setTopBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 4, "000000");
            table.setLeftBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 4, "000000");
            table.setRightBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 4, "000000");
            table.setInsideHBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 4, "000000");
            table.setInsideVBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 4, "000000");
        }
        //输出文件流
        OutputStream outputStream;
        outputStream = new BufferedOutputStream(response.getOutputStream());
        doc.write(outputStream);
        outputStream.flush();
        outputStream.close();
    }

    @Autowired
    private FileInfoBizService fileInfoBizService;

    @PostMapping(value = "/import")
    public RtnInfo<?> importWord(MultipartFile file,
                                 @RequestParam(required = false) String fileDesc,
                                 @RequestParam(required = false) String toolCode) throws Exception {
        XWPFDocument xwpf = new XWPFDocument(file.getInputStream());
        List<XWPFTable> tableList = xwpf.getTables();
        if (tableList.size() > 0) {
            XWPFTable table = tableList.get(0);
            PlanInfo planInfo = new PlanInfo();
            if (StringUtils.isEmpty(table.getRow(0).getCell(1).getText())) {
                return RtnInfo.error(99,"计划分类未填写！");
            }
            if (StringUtils.isEmpty(table.getRow(1).getCell(1).getText())) {
                return RtnInfo.error(99,"计划子类未填写！");
            }
            if (StringUtils.isEmpty(table.getRow(2).getCell(1).getText())) {
                return RtnInfo.error(99,"项目名称未填写！");
            }
            if (StringUtils.isEmpty(table.getRow(3).getCell(1).getText())) {
                return RtnInfo.error(99,"经费预算未填写！");
            }
            if (StringUtils.isEmpty(table.getRow(4).getCell(1).getText())) {
                return RtnInfo.error(99,"已安排经费未填写！");
            }
            if (StringUtils.isEmpty(table.getRow(7).getCell(1).getText())) {
                return RtnInfo.error(99,"计划开始年度未填写！");
            }
            if (StringUtils.isEmpty(table.getRow(8).getCell(1).getText())) {
                return RtnInfo.error(99,"计划结束年度未填写！");
            }
            String value = TranslateUtil.getPlanTypeValue(table.getRow(0).getCell(1).getText(),"plan_type");
            planInfo.setPlanType(value);
            planInfo.setSubType(TranslateUtil.getPlanType(value,table.getRow(1).getCell(1).getText()));
            planInfo.setProjectName(table.getRow(2).getCell(1).getText());
            planInfo.setBudgetFund(BigDecimal.valueOf(Double.parseDouble(table.getRow(3).getCell(1).getText())));
            planInfo.setArrangeFund(BigDecimal.valueOf(Double.parseDouble(table.getRow(4).getCell(1).getText())));
            if (StringUtils.isNotEmpty(table.getRow(5).getCell(1).getText())) {
                planInfo.setYearFund(BigDecimal.valueOf(Double.parseDouble(table.getRow(5).getCell(1).getText())));
            }
            if (StringUtils.isNotEmpty(table.getRow(6).getCell(1).getText())) {
                planInfo.setNextFund(BigDecimal.valueOf(Double.parseDouble(table.getRow(6).getCell(1).getText())));
            }
            planInfo.setStartYear(Integer.valueOf(table.getRow(7).getCell(1).getText()));
            planInfo.setEndYear(Integer.valueOf(table.getRow(8).getCell(1).getText()));
            planInfo.setTaskSource(table.getRow(9).getCell(1).getText());
            planInfo.setTaskSourceExplain(table.getRow(10).getCell(1).getText());
            planInfo.setProjectBackground(table.getRow(11).getCell(1).getText());
            planInfo.setResearchContent(table.getRow(12).getCell(1).getText());
            planInfo.setResultForm(table.getRow(13).getCell(1).getText());
            planInfo.setRemark(table.getRow(14).getCell(1).getText());
            planInfo.setPlanFile(JSON.toJSONString(fileInfoBizService.upload(file, fileDesc, toolCode)));
            return RtnInfo.success(planInfo);
        }
        return RtnInfo.success(null);
    }

    /**
     * 批量审核
     * @param list
     * @return
     */
    @PostMapping(value = "/batchExamine")
    public RtnInfo<?> batchExamine(@RequestBody List<BatchExamineReqItem> list){
        if(CollectionUtils.isEmpty(list)){
            return RtnInfo.error(RtnConstant.Code.PARAMS_REEOR,"审批内容为空");
        }
        list.forEach(item ->{
            PlanInfo planInfo = item.getPlanInfo();
            planInfoService.updateInfoOnly(planInfo);

            FlowBizModel flowBizModel = item.getFlowBizModel();
            flowService.nextStepUpgrade(flowBizModel);
        });
        return RtnInfo.SUCCESS;
    }
}
